package com.example.musicbox.service.impl;

import com.baomidou.mybatisplus.extension.api.R;
import com.example.musicbox.config.CosConfig;
import com.example.musicbox.config.MyException;
import com.example.musicbox.enums.AboutMusic;
import com.example.musicbox.enums.LogDoType;
import com.example.musicbox.service.FileOperationService;
import com.example.musicbox.utils.GeneratorToken;
import com.example.musicbox.utils.Result;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author : zhy
 * @since : 2022/8/1
 */
@Service
@Slf4j
public class FileOperationServiceImpl implements FileOperationService {

    @Resource
    private CosConfig cosConfig;

    @Resource
    private GeneratorToken generatorToken;

    @Resource
    private MLogServiceImpl mLogService;

    private void deleteFile(File... files) {
        for (File file : files) {
            if (file.exists()) {
                file.delete();
            }
        }
    }


    /**
     * 文件上传
     * 应该分类上传 有token代表已经登录，所有只能时视频或者音乐
     * @param file
     * @param token
     * @return
     */
    @Override
    public Result uploadFile(MultipartFile file, String token,String type) {
        int userId=0;
        if(token==null||token.isEmpty()){
            userId=000;
        }else {
            userId = generatorToken.getUserId(token);
        }
        if (file == null) {
            throw new MyException("文件找不到");
        }
        //获取文件的名称
        String oldFileName = file.getOriginalFilename();
        log.info("获取到的文件名称:{}", oldFileName);
        //获取文件扩展名
        String endName = oldFileName.substring(oldFileName.lastIndexOf("."));
        if (type.equals("music"))
        {
            List<String> list = new ArrayList<>();
            list.add(".mp3");
            list.add(".flac");
            list.add(".wav");
            list.add(".m4a");
            if(!list.contains(endName)){
                throw new MyException("音频格式不对");
            }
        }
        if(type.equals("MV")){
            List<String> list = new ArrayList<>();
            list.add(".avi");
            list.add(".mp4");
            list.add(".m4v");
            list.add(".rmvb");
            if(!list.contains(endName)){
                throw new MyException("视频格式不对");
            }
        }
        if(type.equals("photo")){
            List<String> list = new ArrayList<>();
            list.add(".jpg");
            list.add(".jpeg");
            list.add(".png");
            list.add(".ico");
            if(!list.contains(endName)){
                throw new MyException("图片格式不对");
            }
        }
        //拼接新的文件名称
        String newFileName = System.currentTimeMillis() + endName;
        log.info("修改后的文件名称:{}", newFileName);
        //1:初始化用户信息
        COSCredentials cred = new BasicCOSCredentials(cosConfig.getAccesskey(), cosConfig.getSecretKey());
        // 2:设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        ClientConfig clientConfig = new ClientConfig(new Region(cosConfig.getBucket()));
        //3: 生成cos客户端
        COSClient client = new COSClient(cred, clientConfig);
        log.info("腾讯云客户端连接成功");
        //4:填写存储桶的名称，在此需要符合存储桶名称的格式规则 {name}-{appId}
        String bucketName = cosConfig.getBucketName();
        File localFile = null;
        try {
            //创建临时文件，设置前缀和后缀
            localFile = File.createTempFile("temp", null);
            file.transferTo(localFile);
            //设置指定上传位置
            String key = "/" + cosConfig.getQianzui() + "/" + userId + "/" + newFileName;
            log.info("文件上传路径:{}", key);
            PutObjectRequest request = new PutObjectRequest(bucketName, key, localFile);
            //客户端上传文件
            PutObjectResult result = client.putObject(request);
            log.info("文件上传成功");
            deleteFile(localFile);
            log.info("删除临时文件成功");
            mLogService.insertLog("用户上传文件", AboutMusic.NOTHINGABOUTMUSIC,null, LogDoType.INSERT,token);
            return Result.ok().put("path", cosConfig.getPath() + request.getKey());
        } catch (IOException e) {
            e.printStackTrace();
            throw new MyException("文件上传失败");
        } finally {
            client.shutdown();
        }
    }



    /**
     * 文件删除
     * @param key
     * @return
     */
    @Override
    public Result deleteFile(String key,String token) {
        COSClient client = null;
        try {
            //1:初始化用户信息
            COSCredentials cred = new BasicCOSCredentials(cosConfig.getAccesskey(), cosConfig.getSecretKey());
            // 2:设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
            ClientConfig clientConfig = new ClientConfig(new Region(cosConfig.getBucket()));
            //3: 生成cos客户端
            client = new COSClient(cred, clientConfig);
            //4:填写存储桶的名称，在此需要符合存储桶名称的格式规则 {name}-{appId}
            String bucketName = cosConfig.getBucketName();
            key=key.substring(key.lastIndexOf("/emos"));
            DeleteObjectRequest request = new DeleteObjectRequest(bucketName, key);
            /**
             * 删除数据
             */
            client.deleteObject(request);
            mLogService.insertLog("用户删除文件", AboutMusic.NOTHINGABOUTMUSIC,null, LogDoType.DELETE,token);
            return Result.ok("文件删除成功").put("path", cosConfig.getPath() + request.getKey());
        } catch (Exception e) {
            e.printStackTrace();
            throw new MyException("文件删除失败");
        } finally {
            client.shutdown();
        }
    }

    @Override
    public Result downloadFile(String key,String path,String token) {
        COSClient client = null;
        try {
            //1:初始化用户信息
            COSCredentials cred = new BasicCOSCredentials(cosConfig.getAccesskey(), cosConfig.getSecretKey());
            // 2:设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
            ClientConfig clientConfig = new ClientConfig(new Region(cosConfig.getBucket()));
            //3: 生成cos客户端
            client = new COSClient(cred, clientConfig);
            //4:填写存储桶的名称，在此需要符合存储桶名称的格式规则 {name}-{appId}
            String bucketName = cosConfig.getBucketName();
            key=key.substring(key.lastIndexOf("/emos"));
            GetObjectRequest request = new GetObjectRequest(bucketName, key);
            String substring = key.substring(key.lastIndexOf("/")+1);
            client.getObject(request,new File(path+substring));
            mLogService.insertLog("用户下载文件", AboutMusic.DOWNLOADMUSIC,null, LogDoType.INSERT,token);
            return Result.ok("文件下载成功");
        }catch (Exception e){
            throw new MyException("文件下载失败");
        }finally {
            client.shutdown();
        }
    }


    /**
     * 上传头像
     * @param file
     * @return
     */
    public Result uploadPhoto(MultipartFile file){
        if (file == null) {
            throw new MyException("文件找不到");
        }
        //获取文件的名称
        String oldFileName = file.getOriginalFilename();
        log.info("获取到的文件名称:{}", oldFileName);
        //获取文件扩展名
        String endName = oldFileName.substring(oldFileName.lastIndexOf("."));
        ArrayList<String> list = new ArrayList<>();
        list.add(".jpg");
        list.add(".jpeg");
        list.add(".png");
        list.add(".ico");
        if(!list.contains(endName))
        {
            return Result.error("图片格式不对");
        }
        //拼接新的文件名称
        String newFileName = System.currentTimeMillis() + endName;
        log.info("修改后的文件名称:{}", newFileName);
        //1:初始化用户信息
        COSCredentials cred = new BasicCOSCredentials(cosConfig.getAccesskey(), cosConfig.getSecretKey());
        // 2:设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        ClientConfig clientConfig = new ClientConfig(new Region(cosConfig.getBucket()));
        //3: 生成cos客户端
        COSClient client = new COSClient(cred, clientConfig);
        log.info("腾讯云客户端连接成功");
        //4:填写存储桶的名称，在此需要符合存储桶名称的格式规则 {name}-{appId}
        String bucketName = cosConfig.getBucketName();
        File localFile = null;
        try {
            //创建临时文件，设置前缀和后缀
            localFile = File.createTempFile("temp", null);
            file.transferTo(localFile);
            //设置指定上传位置
            String key = "/" + cosConfig.getQianzui() + "/" + "photo" + "/" + newFileName;
            log.info("文件上传路径:{}", key);
            PutObjectRequest request = new PutObjectRequest(bucketName, key, localFile);
            //客户端上传文件
            PutObjectResult result = client.putObject(request);
            log.info("文件上传成功");
            deleteFile(localFile);
            log.info("删除临时文件成功");
            return Result.ok().put("path", cosConfig.getPath() + request.getKey());
        } catch (IOException e) {
            e.printStackTrace();
            throw new MyException("文件上传失败");
        } finally {
            client.shutdown();
        }
    }

}
